package com.gxar.quick.ar.server.base.controller;

import com.gxar.common.entity.Result;
import com.gxar.common.entity.SlippageResult;
import com.gxar.common.entity.SystemCodeEnum;
import com.gxar.common.entity.login.LoginUserThread;
import com.gxar.common.entity.login.UserProfile;
import com.gxar.common.exception.APIRuntimeException;
import com.gxar.common.warning.ApiLog;
import com.gxar.quick.ar.server.base.common.enums.UserWorksSourceEnum;
import com.gxar.quick.ar.server.base.common.enums.UserWorksTypeEnum;
import com.gxar.quick.ar.server.base.common.enums.WorksQueryChannelEnum;
import com.gxar.quick.ar.server.base.facade.ArProtocolConvertFacade;
import com.gxar.quick.ar.server.base.facade.WorksFacade;
import com.gxar.quick.ar.server.base.model.ResultCodeEnum;
import com.gxar.quick.ar.server.base.model.protocol.CommonInputWorkInfo;
import com.gxar.quick.ar.server.base.model.protocol.vo.request.QueryDeliveryListRequest;
import com.gxar.quick.ar.server.base.model.works.vo.request.WorksUpdatePositionRequest;
import com.gxar.quick.ar.server.base.model.works.vo.request.*;
import com.gxar.quick.ar.server.base.model.works.vo.response.*;
import com.gxar.quick.ar.server.db.service.WorksService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 作品接口
 *
 * @author linsy
 * @version 1.0
 * @created 2023/11/3 15:44
 */
@Api(tags = "作品接口")
@RestController
@RequestMapping("/api/works")
@RequiredArgsConstructor
@Slf4j
public class WorksController {

    private final WorksService worksService;

    private final ArProtocolConvertFacade arProtocolConvertFacade;
    private final WorksFacade worksFacade;

    @ApiOperation("作品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "next_id", value = "下一个查询的id", dataType = "string")
    })
    @GetMapping("")
    public Result<SlippageResult<WorksListResponse>> getList(@RequestParam(name = "next_id", required = false) String nextId) {
        UserProfile userProfile = LoginUserThread.get();
        List<Integer> userWorksSourceEnumList = new ArrayList<>(2);
        userWorksSourceEnumList.add(UserWorksSourceEnum.SELF.getCode());
        SlippageResult<WorksListResponse> worksListResponse = worksService.list(userProfile, nextId, UserWorksTypeEnum.MINE, userWorksSourceEnumList, WorksQueryChannelEnum.MINE.getCode());
        return Result.success(worksListResponse);
    }

    @ApiOperation("作品投放列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "next_id", value = "下一个查询的id", dataType = "string"),
            @ApiImplicitParam(name = "type", value = "作品类型：mine-我的，favorites-收藏，exchange-兑换品", dataType = "string"),
    })
    @GetMapping("/delivery")
    public Result<SlippageResult<WorksListResponse>> getDeliveryList(@RequestParam(name = "next_id", required = false) String nextId,
                                                                     @RequestParam(name = "type") String type) {
        UserProfile userProfile = LoginUserThread.get();
        UserWorksTypeEnum userWorksTypeEnum = UserWorksTypeEnum.getByName(type);
        if (Objects.isNull(userWorksTypeEnum)) {
            userWorksTypeEnum = UserWorksTypeEnum.MINE;
        }
        List<Integer> userWorksSourceEnumList = new ArrayList<>(2);
        if (!userWorksTypeEnum.equals(UserWorksTypeEnum.FAVORITES)) {
            userWorksSourceEnumList.add(UserWorksSourceEnum.SELF.getCode());
            userWorksSourceEnumList.add(UserWorksSourceEnum.SHARE.getCode());
        }
        SlippageResult<WorksListResponse> worksListResponse = worksService.list(userProfile, nextId, userWorksTypeEnum, userWorksSourceEnumList, WorksQueryChannelEnum.DELIVERY.getCode());
        return Result.success(worksListResponse);
    }

    @ApiOperation("作品投放列表V2 - 经协议转化")
    @PostMapping("/v2/delivery")
    public Result<SlippageResult<WorksListResponse>> getDeliveryListV2(@RequestBody @Valid QueryDeliveryListRequest request) {
        UserProfile userProfile = LoginUserThread.get();
        UserWorksTypeEnum userWorksTypeEnum = UserWorksTypeEnum.getByName(request.getType());
        if (Objects.isNull(userWorksTypeEnum)) {
            userWorksTypeEnum = UserWorksTypeEnum.MINE;
        }
        List<Integer> userWorksSourceEnumList = new ArrayList<>(2);
        if (!userWorksTypeEnum.equals(UserWorksTypeEnum.FAVORITES)) {
            userWorksSourceEnumList.add(UserWorksSourceEnum.SELF.getCode());
            userWorksSourceEnumList.add(UserWorksSourceEnum.SHARE.getCode());
        }
        SlippageResult<WorksListResponse> worksListResponse = worksService.list(userProfile, request.getNextId(), userWorksTypeEnum, userWorksSourceEnumList, WorksQueryChannelEnum.DELIVERY.getCode());

        if (request.isNeedConvertProtocol()) {
            // 协议内容转化
            worksListResponse.getContent().stream().filter(Objects::nonNull).forEach(inputWorkItem -> {
                CommonInputWorkInfo commonWorkInfo = CommonInputWorkInfo.from(inputWorkItem);
                arProtocolConvertFacade.convertProtocolConfiguration(commonWorkInfo, request);
                inputWorkItem.setIdentify(commonWorkInfo.getIdentify());
                inputWorkItem.setContent(commonWorkInfo.getContent());
            });
        }
        return Result.success(worksListResponse);
    }

    @ApiOperation("查看作品详情")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @GetMapping("/{id}")
    public Result<WorksInfoResponse> getDetail(@PathVariable(name = "id") Long id) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.getDetail(userProfile, id);
    }

    @ApiOperation("作品更新")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @PutMapping("/{id}")
    public Result<WorksUpdateResponse> updateWorks(@PathVariable(name = "id") Long id, @RequestBody WorksUpdateRequest worksUpdateRequest) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.updateWorks(userProfile, id, worksUpdateRequest);
    }

    @ApiOperation("客户端更新作品位置信息 - 经协议转化")
    @PostMapping("/v2/updateWorksPositionByClient")
    public Result<WorksUpdateResponse> updateWorksPositionByClient(@Valid @RequestBody WorksUpdatePositionRequest request) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.updateWorksPositionByClient(userProfile, request);
    }

    @ApiOperation("作品删除")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @DeleteMapping("/{id}")
    public Result<Boolean> deleteWorks(@PathVariable(name = "id") Long id) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.deleteWorks(userProfile, id);
    }

    @ApiOperation("批量作品删除")
    @DeleteMapping("")
    public Result<Boolean> batchDeleteWorks(@RequestBody BatchDeleteWorksRequest request) {
        List<Long> ids = request.getIds();
        if (CollectionUtils.isEmpty(ids)) {
            throw new APIRuntimeException(ResultCodeEnum.WORK_IDS_NOT_NULL);
        }
        UserProfile userProfile = LoginUserThread.get();
        return worksService.batchDeleteWorks(userProfile, ids);
    }

    @ApiOperation("发布作品")
    @PostMapping("/publish")
    @ApiLog
    public Result<WorksPublishResponse> publish(@RequestBody @Valid WorksPublishRequest worksPublishRequest) {
        UserProfile userProfile = LoginUserThread.get();
        WorksPublishResponse worksPublishResponse = worksService.publish(userProfile, worksPublishRequest);
        return Result.success(worksPublishResponse);
    }

    @ApiOperation("作品分享")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "string", required = true, paramType = "path")
    @PostMapping("/share/{id}")
    public Result<WorksShareResponse> share(@PathVariable(name = "id") String id) {
        UserProfile userProfile = LoginUserThread.get();
        if (StringUtils.isBlank(id) || "null".equals(id)) {
            return Result.error(SystemCodeEnum.PARAM_ERROR);
        }
        WorksShareResponse worksShareResponse = worksService.share(userProfile, Long.parseLong(id));
        return Result.success(worksShareResponse);
    }

    @ApiOperation("根据分享二维码查询作品")
    @GetMapping("/share-detail")
    @ApiLog
    public Result<WorksShareInfoResponse> getDetailByWorksId(@RequestParam String id) {
        UserProfile userProfile = LoginUserThread.get();
        if (StringUtils.isBlank(id) || "null".equals(id)) {
            return Result.error(ResultCodeEnum.WORK_SHARE_INFO_ERROR);
        }
        return worksFacade.getDetailByWorksId(userProfile, id);
    }

    @ApiOperation("作品收藏")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @PostMapping("/favorites/{id}")
    public Result<WorksFavoritesResponse> favorites(@PathVariable(name = "id") Long id) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.favorites(userProfile, id);
    }

    @ApiOperation("取消作品收藏")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @PostMapping("/favorites/cancel/{id}")
    public Result<WorksFavoritesResponse> cancelFavorites(@PathVariable(name = "id") Long id) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.cancelFavorites(userProfile, id);
    }

    @ApiOperation("作品识别")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @PostMapping("/scan/{id}")
    public Result<WorksScanResponse> scan(@PathVariable(name = "id") Long id) {
        UserProfile userProfile = LoginUserThread.get();
        return worksService.scan(userProfile, id);
    }

    @ApiOperation("作品分享删除")
    @ApiImplicitParam(name = "id", value = "作品id", dataType = "long", required = true, paramType = "path")
    @DeleteMapping("/share/{id}")
    @ApiLog
    public Result<WorksShareDeleteResponse> shareDelete(@PathVariable(name = "id") Long id) {
        UserProfile userProfile = LoginUserThread.get();
        WorksShareDeleteResponse worksShareDeleteResponse = worksFacade.shareDelete(userProfile, id);
        return Result.success(worksShareDeleteResponse);
    }

    @ApiOperation("作品转移")
    @PostMapping("/transfer")
    public Result<WorkTransferResponse> transfer(@RequestBody WorkTransferRequest request) {
        UserProfile userProfile = LoginUserThread.get();
        if (CollectionUtils.isEmpty(request.getWorksId())) {
            throw new APIRuntimeException(ResultCodeEnum.TRANSFER_WORK_IDS_NOT_NULL);
        }
        WorkTransferResponse response = worksService.transferWorks(userProfile, request);
        return Result.success(response);
    }

    @ApiOperation("作品转移领取")
    @PostMapping("/transfer-receive")
    public Result<WorkTransferReceiveResponse> transferReceive(@RequestBody WorkTransferReceiveRequest request) {
        UserProfile userProfile = LoginUserThread.get();
        WorkTransferReceiveResponse response = worksService.transferReceive(userProfile, request);
        return Result.success(response);
    }

}
